package com.xieman.anti.replay.utils;

import com.xieman.anti.replay.exception.ArgumentException;
import io.micrometer.common.lang.Nullable;
import org.apache.commons.collections4.MapUtils;
import org.springframework.util.ObjectUtils;

import java.util.Map;
import java.util.Objects;

public class StringUtils extends org.apache.commons.lang3.StringUtils {

    private static final String TEMPLATE_PLACEHOLDER_PREFIX = "{";
    private static final String TEMPLATE_PLACEHOLDER_SUFFIX = "}";

    /**
     * 替换参数
     *
     * @param template 模板
     * @param params 参数
     * @return 替换后的结果
     */
    public static String format(String template, Object... params) {

        if (isBlank(template) || Objects.isNull(params)) {
            return template;
        }

        int i = 0;

        while (i < params.length && template.contains(TEMPLATE_PLACEHOLDER_PREFIX)) {
            int index = template.indexOf(TEMPLATE_PLACEHOLDER_SUFFIX), strLen = template.length();

            if (index == strLen - 1) {
                template = template.substring(0, template.indexOf(TEMPLATE_PLACEHOLDER_PREFIX)) + params[i];
            } else {
                template =
                        template.substring(0, template.indexOf(TEMPLATE_PLACEHOLDER_PREFIX))
                                + params[i]
                                + template.substring(template.indexOf(TEMPLATE_PLACEHOLDER_SUFFIX) + 1);
            }

            i++;
        }

        return template;
    }

    /**
     * 字符串以指定前缀开始
     *
     * @param str 字符串
     * @param prefix 前缀
     * @return 结果
     */
    public static String startAt(String str, CharSequence prefix) {
        if (startsWith(str, prefix)) {
            return str;
        } else {
            return prefix + str;
        }
    }

    /**
     * 字符串以指定前缀结尾
     *
     * @param str 字符串
     * @param suffix 后缀
     * @return 结果
     */
    public static String endAt(String str, CharSequence suffix) {
        if (endsWith(str, suffix)) {
            return str;
        } else {
            return str + suffix;
        }
    }

    /**
     * 字符串转Long
     *
     * @param str 字符串
     * @return Long value
     */
    public static Long convertToLong(String str) {
        if (!isNumeric(str)) {
            throw new ArgumentException(format("非法参数:[ {} ]", str));
        }

        return Long.valueOf(str);
    }

    /**
     * 字符串转Integer
     *
     * @param str 字符串
     * @return Integer value
     */
    public static Integer convertToInteger(String str) {
        if (!isNumeric(str)) {
            throw new ArgumentException(format("非法参数:[ {} ]", str));
        }

        return Integer.valueOf(str);
    }

    public static String convertToUrlParams(Map<String, String> paramMap) {
        if (MapUtils.isNotEmpty(paramMap)) {
            StringBuffer sb = new StringBuffer("?");
            paramMap.forEach((key, val) -> sb.append(key).append('=').append(val).append('&'));

            return trimTrailingCharacter(sb.toString(), '&');
        }

        return "";
    }

    public static String trimTrailingCharacter(String str, char trailingCharacter) {
        if (isBlank(str)) {
            return str;
        } else {
            StringBuilder sb = new StringBuilder(str);

            while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) {
                sb.deleteCharAt(sb.length() - 1);
            }

            return sb.toString();
        }
    }

    /**
     * 使用指定分隔符，拼接字符串
     *
     * @param delimiter 分隔符
     * @param strs      需要拼接的多个字符串，可以为null
     * @return 拼接后的新字符串
     */
    public static String joinStr(String delimiter, @Nullable String... strs) {
        if (ObjectUtils.isEmpty(strs)) {
            return StringUtils.EMPTY;
        }
        StringBuilder sbd = new StringBuilder();
        for (int i = 0; i < strs.length; i++) {
            if (ObjectUtils.isEmpty(strs[i])) {
                continue;
            }
            sbd.append(strs[i].trim());
            if (!ObjectUtils.isEmpty(sbd) && i < strs.length - 1 && !ObjectUtils.isEmpty(strs[i + 1])) {
                sbd.append(delimiter);
            }
        }
        return sbd.toString();

    }
}